home *** CD-ROM | disk | FTP | other *** search
/ Maclife 157 / MACLIFE157-2001-09.ISO.7z / MACLIFE157-2001-09.ISO / Linux / MacOS Tools / Other / BootX 1.1.3 (for Old Mac OS) / Sources / utils / GrabG3CacheSetting / GrabG3CacheSetting.c < prev    next >
C/C++ Source or Header  |  2001-07-23  |  5KB  |  243 lines

  1. /*
  2.  * GrabG3CacheSettings
  3.  *
  4.  * Tool for capturing L2CR value of G3 processors.
  5.  *
  6.  * Written by BenH with code from Terry Greeniaus (thanks Terry)
  7.  *
  8.  * This software is distributed under the GNU Public Licence
  9.  * (see the file COPYING for more details).
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <time.h>
  16. #include <string.h>
  17.  
  18. #include <Memory.h>
  19. #include <Devices.h>
  20. #include <Gestalt.h>
  21. #include <Resources.h>
  22. #include <Folders.h>
  23. #include <Errors.h>
  24.  
  25. #define FUNC_ADDR(x) ((unsigned long*)x)[0]
  26.  
  27. typedef struct MyInterruptPatchData
  28. {
  29.     unsigned long    originalVector;
  30.     unsigned long    r4;
  31.     unsigned long    cr;
  32.     unsigned long    code[];
  33. }MyInterruptPatchData;
  34.  
  35. OSErr LocateBootXPrefsFile(FSSpec *outSpec);
  36. void InstallInterruptPatch(void);
  37. void RemoveInterruptPatch(void);
  38. UInt32 MySCInstruction(void);
  39. Ptr GetPhysicalAddress(void* ptr);
  40. void InterruptPatchCode(void);
  41. void InterruptPatchCodeEnd(void);
  42.  
  43. MyInterruptPatchData*    gDatas;
  44.  
  45. #define PRG1    273
  46. #define PRG2    274
  47. #define L2CR    1017
  48. #define MSR_PR    17
  49.  
  50. int main(void)
  51. {
  52.     long cpuFamily;
  53.     UInt32 l2cr;
  54.     OSErr err;
  55.     FSSpec spec;
  56.     short prefFileRef;
  57.     Handle rsrc;
  58.     
  59.     printf("Querying CPU family...¥n");
  60.  
  61.     err = Gestalt(gestaltNativeCPUfamily, &cpuFamily);
  62.     if (err != noErr)
  63.     {
  64.         printf("Error %d in Gestalt()¥n");
  65.         exit(0);
  66.     }
  67.     if (cpuFamily != gestaltCPU750)
  68.     {
  69.         printf("Error, CPU is not a G3¥n");
  70.         exit(0);
  71.     }
  72.     printf ("Getting value of G3 L2CR register ...¥n");
  73.  
  74.     gDatas = NULL;
  75.     InstallInterruptPatch();
  76.     l2cr = MySCInstruction();
  77.     RemoveInterruptPatch();
  78.  
  79.     printf("L2CR value is: 0x%08lx, saving...¥n", l2cr);
  80.  
  81.     err = LocateBootXPrefsFile(&spec);
  82.     
  83.     if (err != noErr)
  84.     {
  85.         printf("Error %d, Can't find BootX preferences file¥n", err);
  86.         exit(0);
  87.     }
  88.     
  89.     prefFileRef = FSpOpenResFile(&spec, fsWrPerm);
  90.     if (prefFileRef == -1)
  91.     {
  92.         err = ResError();
  93.         if (err == noErr) err = -1;
  94.         printf("Error %d, could not open BootX prefs file¥n", err);
  95.         exit(0);
  96.     }
  97.  
  98.     UseResFile(prefFileRef);
  99.     rsrc = Get1Resource('L2CR', 0);
  100.     if (rsrc)
  101.     {
  102.         RemoveResource(rsrc);
  103.         DisposeHandle(rsrc);
  104.     }
  105.     rsrc = NewHandle(4);
  106.     *((UInt32 *)(*rsrc)) = l2cr;
  107.     AddResource(rsrc, 'L2CR', 0, "¥p");
  108.     WriteResource(rsrc);
  109.     CloseResFile(prefFileRef);
  110.     
  111.     printf("Done.¥n¥nThe ¥"Set G3 Cache¥" option in BootX should now be available.¥n");
  112.     
  113.     return 0;
  114. }
  115.  
  116. OSErr
  117. LocateBootXPrefsFile(FSSpec *outSpec)
  118. {
  119.     CInfoPBRec    pb;
  120.     OSErr err;
  121.     int i;
  122.  
  123.     err = FindFolder(    kOnSystemDisk,
  124.                         kPreferencesFolderType,
  125.                         false,
  126.                         &outSpec->vRefNum,
  127.                         &outSpec->parID);
  128.     if (err != noErr)
  129.         return err;
  130.     
  131.     i=0;
  132.     do
  133.     {
  134.         memset(&pb, 0, sizeof(CInfoPBRec));
  135.         pb.hFileInfo.ioNamePtr = outSpec->name;
  136.         pb.hFileInfo.ioVRefNum = outSpec->vRefNum;
  137.         pb.hFileInfo.ioDirID = outSpec->parID;
  138.         pb.hFileInfo.ioFDirIndex = ++i;
  139.         err = PBGetCatInfoSync(&pb);
  140.         if ((err == noErr) && ((pb.hFileInfo.ioFlAttrib & ioDirMask) == 0)
  141.             && (pb.hFileInfo.ioFlFndrInfo.fdCreator == 'BooX')
  142.             && (pb.hFileInfo.ioFlFndrInfo.fdType == 'pref'))
  143.             return noErr;
  144.     } while(err == noErr);
  145.     
  146.     return fnfErr;
  147. }
  148.  
  149. void InstallInterruptPatch(void)
  150. {
  151.     void*                    myPatchPhys;
  152.     unsigned long            codeLen;
  153.     MyInterruptPatchData*    myPatch;
  154.     
  155.     codeLen =  FUNC_ADDR(InterruptPatchCodeEnd) - FUNC_ADDR(InterruptPatchCode);
  156.     myPatch =  (MyInterruptPatchData*)NewPtrSys(sizeof(MyInterruptPatchData) + codeLen);
  157.     myPatch->originalVector            = *(unsigned long*)0x5FFFE450;
  158.     gDatas = myPatch;
  159.         
  160.     BlockMove((void *)FUNC_ADDR(InterruptPatchCode),myPatch->code,codeLen);
  161.     LockMemoryContiguous(myPatch,sizeof(MyInterruptPatchData) + codeLen);
  162.     MakeDataExecutable(myPatch->code,codeLen);
  163.  
  164.     myPatchPhys = GetPhysicalAddress(myPatch->code);
  165.     *(unsigned long*)0x5FFFE450 = (unsigned long)myPatchPhys;
  166. }
  167.  
  168. Ptr
  169. GetPhysicalAddress(void* ptr)
  170. {
  171.     LogicalToPhysicalTable    table;
  172.     unsigned long            count;
  173.     OSErr                    err;
  174.     
  175.     table.logical.address    = ptr;
  176.     table.logical.count        = 1024;
  177.     count = sizeof( table ) / sizeof( MemoryBlock ) - 1;
  178.     
  179.     err = GetPhysical( &table, &count );
  180.     if ( err != noErr)
  181.         return ptr;
  182.     
  183.     return ( Ptr ) ( table.physical[0].address );
  184. }
  185.  
  186. void RemoveInterruptPatch(void)
  187. {
  188.     *(unsigned long*)0x5FFFE450 = gDatas->originalVector;
  189. }
  190.  
  191. asm UInt32 MySCInstruction(void)
  192. {
  193.     lis    r3,'Bo';
  194.     ori    r3,r3,'oX';
  195.     sc;
  196.     mr r3, r4
  197.     blr;
  198. }
  199.  
  200. asm void InterruptPatchCode(void)
  201. {
  202.     // Get our data area
  203.     subi    sp,sp,sizeof(MyInterruptPatchData);
  204.     
  205.     // Save some registers
  206.     stw    r4,MyInterruptPatchData.r4(sp);
  207.     mfcr    r4;
  208.     stw    r4,MyInterruptPatchData.cr(sp);    
  209.  
  210.     // Test the r3 key
  211.     lis    r4,'Bo';
  212.     ori    r4,r4,'oX';
  213.     cmpw    r3,r4;
  214.     bne    @callOriginalVector;
  215.  
  216.     // OK, it's for us!  Fix everything up and go home.  We don't need
  217.     // to fix r4, since that's a volatile register the way we
  218.     // are accessed.  Also turn off MSR[PR] bit.
  219.     lwz    r4,MyInterruptPatchData.cr(sp);
  220.     mtcrf    0xFF,r4;
  221.     mfspr   r4,PRG2;
  222.     mtlr    r4;
  223.     mfspr     sp, PRG1;
  224.     mfsrr1    r4;
  225.     rlwinm    r4,r4,0,MSR_PR+1,MSR_PR-1;    // MSR_PR == MSR[PR] bit number
  226.     mfspr    r4,L2CR
  227.     rfi;
  228.  
  229. @callOriginalVector:
  230.     // OK, we need to call the original vector, since it wasn't for us.
  231.     // Restore the cr and r4, and set up sp the way it would have been
  232.     // set up for us (i.e. sp contains the address of the original vector
  233.     // code and we move it to lr and do a blrl like ROM does).
  234.     lwz    r4,MyInterruptPatchData.cr(sp);
  235.     mtcrf    0xFF,r4;
  236.     lwz    r4,MyInterruptPatchData.r4(sp);
  237.     lwz    sp,MyInterruptPatchData.originalVector(sp);
  238.     mtlr    sp;
  239.     blrl;
  240. entry InterruptPatchCodeEnd
  241. InterruptPatchCodeEnd:    
  242. }
  243.